package com.yanghui.dtracing.core.plugin.interceptor;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yanghui.dtracing.common.util.Result;
import com.yanghui.dtracing.core.log.ILog;
import com.yanghui.dtracing.core.log.LogManager;
import com.yanghui.dtracing.core.opentracing.Tracing;
import com.yanghui.dtracing.core.opentracing.log.LogData;
import io.opentracing.Span;
import io.opentracing.tag.Tags;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

public abstract class AbstractMethodInterceptor {

    private static final ILog log = LogManager.getLogger(AbstractMethodInterceptor.class);

    protected void parseResult(Span span,MethodInterceptResult methodInterceptResult){
        try{
            if(methodInterceptResult.isHasException()){
                return;
            }
            Object result = methodInterceptResult.getResult();
            boolean success = true;
            if(result == null){
                return;
            }
            if(result instanceof Result){
                Result result1 = (Result)result;
                if(!result1.isSuccess()){
                    success = false;
                }
            }else if(result instanceof String){
                boolean isJson = JSONUtil.isJson(result.toString());
                if(isJson){
                    JSONObject jsonObject = JSONUtil.parseObj(result.toString());
                    if(jsonObject != null && jsonObject.getInt("code") != null){
                        if(jsonObject.getInt("code") != 0 && null != jsonObject.getStr("desc")){
                            success = false;
                        }
                    }
                }
            }
            if(!success){
                span.setTag(Tags.ERROR.getKey(),true);
            }
        }catch (Throwable t){
            log.error("AbstractMethodInterceptor.parseResult exception.",t);
        }
    }

    protected Span exception(Throwable t){
        Span span = Tracing.getTracer().activeSpan()
                .setTag(Tags.ERROR.getKey(),true);
        StringWriter writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        t.printStackTrace(printWriter);
        Map<String,Object> builder = new HashMap<>();
        builder.put(LogData.EVENT_TYPE_KEY, LogData.EVENT_ERROR_VALUE);
        builder.put(LogData.ERROR_KIND_KEY,t.getClass().getSimpleName());
        builder.put(LogData.ERROR_OBJECT_KEY,t.getClass().getName());
        builder.put(LogData.MESSAGE_KEY,t.getMessage());
        builder.put(LogData.STACK_KEY,writer.toString());
        span.log(builder);
        return span;
    }
}
